import 'dart:convert';

/// 短剧信息模型
class PAGSShort {
  final int? id; //短剧id
  final String? title; //短剧标题
  final int? total; //总集数
  final int? progressState; // 1完结 2未完结
  final int? firstOnlineTime; //上架时间
  final String? desc; //短剧描述
  final String? coverImage; //封面图
  final String? language; //语言 （IOS有/安卓没有）
  final List<PAGSCategory>?
  categories; //分类 [{'id',1,'name':'爱情'},{'id',1,'name':'霸总'}]
  final List<PAGSTag>?
  tags; //标签 [{'tag_id',1,'tag_name':'7DCollect'},{'tag_id',1,'tag_name':'7DCollect'}]
  final int? sType; //不知道，（IOS没有/安卓有）
  final int? totalCollectCount; //总收藏数
  final List<PAGSEpisode>? episodes; //正常是集数列表，但是只返回一个
  final bool? isCollected; //是否收藏

  PAGSShort({
    this.id,
    this.title,
    this.desc,
    this.categories,
    this.coverImage,
    this.total,
    this.progressState,
    this.language,
    this.episodes,
    this.totalCollectCount,
    this.isCollected,
    this.sType,
    this.tags,
    this.firstOnlineTime,
  });

  factory PAGSShort.fromMap(Map m) {
    return PAGSShort(
      id: m['id'] ?? 0,
      title: m['title']?.toString() ?? '',
      desc: m['desc']?.toString() ?? '',
      categories:
          (m['categories'] as List<dynamic>?)
              ?.map((e) => PAGSCategory.fromMap(e as Map))
              .toList() ??
          [],
      coverImage: m['cover_image']?.toString() ?? '',
      total: m['total'] ?? 0,
      progressState: m['progress_state'] ?? 2,
      language: m['language']?.toString() ?? '',
      episodes:
          (m['episodes'] as List<dynamic>?)
              ?.map((e) => PAGSEpisode.fromMap(e as Map))
              .toList() ??
          [],
      totalCollectCount: m['totalCollectCount'] ?? 0,
      isCollected: m['isCollected'] as bool? ?? false,
      sType: m['sType'] ?? 0,
      tags:
          (m['tags'] as List<dynamic>?)
              ?.map((e) => PAGSTag.fromMap(e as Map))
              .toList() ??
          [],
      firstOnlineTime: m['firstOnlineTime'] ?? 0,
    );
  }

  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'title': title,
      'desc': desc,
      'categories': categories?.map((e) => e.toMap()).toList(),
      'coverImage': coverImage,
      'total': total,
      'progressState': progressState,
      'language': language,
      'episodes': episodes?.map((e) => e.toMap()).toList(),
      'totalCollectCount': totalCollectCount,
      'isCollected': isCollected,
      'sType': sType,
      'tags': tags?.map((e) => e.toMap()).toList(),
      'firstOnlineTime': firstOnlineTime,
    };
  }

  /// 创建一个新的 PAGSShort 实例，可选择性地更新字段
  /// Create a new PAGSShort instance with optionally updated fields
  PAGSShort copyWith({
    int? id,
    String? title,
    int? total,
    int? progressState,
    int? firstOnlineTime,
    String? desc,
    String? coverImage,
    String? language,
    List<PAGSCategory>? categories,
    List<PAGSTag>? tags,
    int? sType,
    int? totalCollectCount,
    List<PAGSEpisode>? episodes,
    bool? isCollected,
  }) {
    return PAGSShort(
      id: id ?? this.id,
      title: title ?? this.title,
      desc: desc ?? this.desc,
      categories: categories ?? this.categories,
      coverImage: coverImage ?? this.coverImage,
      total: total ?? this.total,
      progressState: progressState ?? this.progressState,
      language: language ?? this.language,
      episodes: episodes ?? this.episodes,
      totalCollectCount: totalCollectCount ?? this.totalCollectCount,
      isCollected: isCollected ?? this.isCollected,
      sType: sType ?? this.sType,
      tags: tags ?? this.tags,
      firstOnlineTime: firstOnlineTime ?? this.firstOnlineTime,
    );
  }
}

/// 分类模型
class PAGSCategory {
  final int id;
  final String? name;
  final int? count;

  PAGSCategory({required this.id, this.name, this.count});

  factory PAGSCategory.fromMap(Map m) {
    int categoryId = m['id'] ?? 0;
    String categoryName = m['name']?.toString() ?? '';
    int count = m['count'] ?? 0;
    return PAGSCategory(id: categoryId, name: categoryName, count: count);
  }

  Map<String, dynamic> toMap() {
    return {'id': id, 'name': name, 'count': count};
  }
}

/// 标签模型
class PAGSTag {
  final int tagId;
  final String? tagName;

  PAGSTag({required this.tagId, this.tagName});

  factory PAGSTag.fromMap(Map m) {
    return PAGSTag(tagId: m['tag_id'] ?? 0, tagName: m['tag_name'] as String?);
  }

  Map<String, dynamic> toMap() {
    return {'tag_id': tagId, 'tag_name': tagName};
  }
}

/// 剧集信息模型
class PAGSEpisode {
  final int? index;
  final int? id;
  final String? vid;
  final String? country;
  final int? expireTime;
  final int? totalLikeCount;
  final bool? isLiked;
  final String? playInfoListData;
  final List<PAGSPlayInfo>? playInfoList;

  PAGSEpisode({
    this.index,
    this.id,
    this.vid,
    this.country,
    this.expireTime,
    this.totalLikeCount,
    this.isLiked,
    this.playInfoListData,
    this.playInfoList,
  });

  factory PAGSEpisode.fromMap(Map m) {
    // 兼容处理：优先使用新字段，如果没有则使用旧字段
    int? episodeIndex = m['index'] ?? 0;
    int? episodeId = m['id'] ?? 0;
    String? vid = m['vid']?.toString() ?? '';

    final String playInfoData = m['playInfoListData']?.toString() ?? '';
    List<PAGSPlayInfo>? parsedPlayInfo;
    if (playInfoData.isNotEmpty) {
      try {
        final List<dynamic> decoded = jsonDecode(playInfoData) as List<dynamic>;
        parsedPlayInfo = decoded
            .map(
              (e) => e is Map
                  ? PAGSPlayInfo.fromMap(
                      e.map((key, value) => MapEntry(key.toString(), value)),
                    )
                  : null,
            )
            .whereType<PAGSPlayInfo>()
            .toList();
      } catch (_) {
        parsedPlayInfo = null;
      }
    }

    final List<PAGSPlayInfo>? playInfoList =
        parsedPlayInfo ??
        (m['PlayInfoList'] is List
            ? (m['PlayInfoList'] as List)
                  .map(
                    (e) => e is Map
                        ? PAGSPlayInfo.fromMap(
                            e.map(
                              (key, value) => MapEntry(key.toString(), value),
                            ),
                          )
                        : null,
                  )
                  .whereType<PAGSPlayInfo>()
                  .toList()
            : null);

    return PAGSEpisode(
      index: episodeIndex,
      id: episodeId,
      vid: vid,
      country: m['country']?.toString() ?? '',
      expireTime: m['expireTime'] ?? 0,
      totalLikeCount: m['totalLikeCount'] ?? 0,
      isLiked: m['isLiked'] as bool? ?? false,
      playInfoListData: playInfoData,
      playInfoList: playInfoList,
    );
  }

  Map<String, dynamic> toMap() {
    List<Map<String, dynamic>>? playInfoMaps = playInfoList
        ?.map((e) => e.toMap())
        .toList();
    String? encodedPlayInfo;
    if ((playInfoMaps?.isNotEmpty ?? false)) {
      try {
        encodedPlayInfo = jsonEncode(playInfoMaps);
      } catch (_) {
        encodedPlayInfo = playInfoListData;
      }
    } else {
      encodedPlayInfo = playInfoListData;
    }

    return {
      'index': index ?? 0,
      'id': id ?? 0,
      'vid': vid,
      'country': country,
      'expireTime': expireTime ?? 0,
      'totalLikeCount': totalLikeCount,
      'isLiked': isLiked,
      'playInfoListData': encodedPlayInfo ?? '',
      if (playInfoMaps != null) 'PlayInfoList': playInfoMaps,
    };
  }
}

/// 播放源信息
class PAGSPlayInfo {
  final String? fileId;
  final String? md5;
  final String? mainPlayUrl;
  final String? backupPlayUrl;
  final String? playAuthId;
  final String? playAuth;
  final String? definition;
  final String? fileType;
  final String? format;
  final String? codec;
  final int? bitrate;
  final int? width;
  final int? height;
  final int? size;
  final double? duration;
  final String? keyFrameAlignment;
  final String? mainUrlExpire;
  final String? backupUrlExpire;
  final String? quality;
  final String? checkInfo;
  final int? barrageMaskOffset;

  PAGSPlayInfo({
    this.fileId,
    this.md5,
    this.mainPlayUrl,
    this.backupPlayUrl,
    this.playAuthId,
    this.playAuth,
    this.definition,
    this.fileType,
    this.format,
    this.codec,
    this.bitrate,
    this.width,
    this.height,
    this.size,
    this.duration,
    this.keyFrameAlignment,
    this.mainUrlExpire,
    this.backupUrlExpire,
    this.quality,
    this.checkInfo,
    this.barrageMaskOffset,
  });

  factory PAGSPlayInfo.fromMap(Map<String, dynamic> map) {
    return PAGSPlayInfo(
      fileId: map['FileId']?.toString(),
      md5: map['Md5']?.toString(),
      mainPlayUrl: map['MainPlayUrl']?.toString(),
      backupPlayUrl: map['BackupPlayUrl']?.toString(),
      playAuthId: map['PlayAuthId']?.toString(),
      playAuth: map['PlayAuth']?.toString(),
      definition: map['Definition']?.toString(),
      fileType: map['FileType']?.toString(),
      format: map['Format']?.toString(),
      codec: map['Codec']?.toString(),
      bitrate: map['Bitrate'] is int
          ? map['Bitrate'] as int?
          : int.tryParse(map['Bitrate']?.toString() ?? ''),
      width: map['Width'] is int
          ? map['Width'] as int?
          : int.tryParse(map['Width']?.toString() ?? ''),
      height: map['Height'] is int
          ? map['Height'] as int?
          : int.tryParse(map['Height']?.toString() ?? ''),
      size: map['Size'] is int
          ? map['Size'] as int?
          : int.tryParse(map['Size']?.toString() ?? ''),
      duration: map['Duration'] is num
          ? (map['Duration'] as num).toDouble()
          : double.tryParse(map['Duration']?.toString() ?? ''),
      keyFrameAlignment: map['KeyFrameAlignment']?.toString(),
      mainUrlExpire: map['MainUrlExpire']?.toString(),
      backupUrlExpire: map['BackupUrlExpire']?.toString(),
      quality: map['Quality']?.toString(),
      checkInfo: map['CheckInfo']?.toString(),
      barrageMaskOffset: map['BarrageMaskOffset'] is int
          ? map['BarrageMaskOffset'] as int?
          : int.tryParse(map['BarrageMaskOffset']?.toString() ?? ''),
    );
  }

  Map<String, dynamic> toMap() {
    return {
      if (fileId != null) 'FileId': fileId,
      if (md5 != null) 'Md5': md5,
      if (mainPlayUrl != null) 'MainPlayUrl': mainPlayUrl,
      if (backupPlayUrl != null) 'BackupPlayUrl': backupPlayUrl,
      if (playAuthId != null) 'PlayAuthId': playAuthId,
      if (playAuth != null) 'PlayAuth': playAuth,
      if (definition != null) 'Definition': definition,
      if (fileType != null) 'FileType': fileType,
      if (format != null) 'Format': format,
      if (codec != null) 'Codec': codec,
      if (bitrate != null) 'Bitrate': bitrate,
      if (width != null) 'Width': width,
      if (height != null) 'Height': height,
      if (size != null) 'Size': size,
      if (duration != null) 'Duration': duration,
      if (keyFrameAlignment != null) 'KeyFrameAlignment': keyFrameAlignment,
      if (mainUrlExpire != null) 'MainUrlExpire': mainUrlExpire,
      if (backupUrlExpire != null) 'BackupUrlExpire': backupUrlExpire,
      if (quality != null) 'Quality': quality,
      if (checkInfo != null) 'CheckInfo': checkInfo,
      if (barrageMaskOffset != null) 'BarrageMaskOffset': barrageMaskOffset,
    };
  }
}

/// SDK配置模型
class PAGSSDKConfig {
  final String appId;
  final String vodAppId;
  final String securityKey;
  final String licenseAssertPath;
  final String? userId;
  final bool debug;

  PAGSSDKConfig({
    required this.appId,
    required this.vodAppId,
    required this.securityKey,
    required this.licenseAssertPath,
    this.userId,
    this.debug = false,
  });

  Map<String, dynamic> toMap() {
    return {
      'appId': appId,
      'vodAppId': vodAppId,
      'securityKey': securityKey,
      'licenseAssertPath': licenseAssertPath,
      'userId': userId,
      'debug': debug,
    };
  }
}

/// 分类项模型
class PAGSCategoryItem {
  final int categoryId;
  final String categoryName;

  PAGSCategoryItem({required this.categoryId, required this.categoryName});

  factory PAGSCategoryItem.fromMap(Map<String, dynamic> map) {
    return PAGSCategoryItem(
      categoryId: map['category_id'] ?? 0,
      categoryName: map['category_name'] ?? '',
    );
  }

  Map<String, dynamic> toMap() {
    return {'category_id': categoryId, 'category_name': categoryName};
  }
}

/// 短剧列表响应
class PAGSFeedListResponse {
  final List<PAGSShort> list;
  final bool hasMore;
  final String? error;

  PAGSFeedListResponse({required this.list, required this.hasMore, this.error});

  factory PAGSFeedListResponse.fromMap(Map<String, dynamic> map) {
    final rawList = map['list'] as List<dynamic>?;
    final list =
        rawList?.map((e) => PAGSShort.fromMap(e as Map)).toList() ?? [];
    return PAGSFeedListResponse(
      list: list,
      hasMore: map['hasMore'] ?? false,
      error: map['error'] as String?,
    );
  }
}
